#include <fcntl.h>

#include <sys/mman.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <linux/fb.h>

#include <stdint.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <termios.h>

#include <sys/types.h>

#include <sys/stat.h>

#include "as608_test.h"

uint32_t AS608Addr = 0XFFFFFFFF; // 默认

static uint8_t rx_buffer[64];

int fd;

// 初始化PA6为下拉输入

// 读摸出感应状态(触摸感应时输出高电平信号)

/*void PS_StaGPIO_Init(void)



{



	RCC->APB1ENR |= 1<<2;//使能PORTA时钟



	GPIOA->CRL &=0XF0FFFFFF;//复位PA6



	GPIOA->CRL |=0X08000000;//输入模式，默认下拉



	GPIOA->ODR &=~(1<<6);//下拉



}*/

// 串口发送一个字节

int init_tty(int fd)

{

	struct termios old_flags, new_flags;

	bzero(&new_flags, sizeof(new_flags));

	// 1. 获取旧的属性

	tcgetattr(fd, &old_flags);

	// 2. 设置原始模式

	cfmakeraw(&new_flags);

	// 3. 激活本地连接CLOCAL与接收使能CREAD的选项

	new_flags.c_cflag |= CLOCAL | CREAD;

	// 4. 设置波特率

	cfsetispeed(&new_flags, B9600);

	cfsetospeed(&new_flags, B9600);

	// 5. 设置数据位为8位

	new_flags.c_cflag &= ~CSIZE; // 清空原有的数据位

	new_flags.c_cflag |= CS8;

	// 6. 设置奇偶检验位

	new_flags.c_cflag &= ~PARENB;

	// 7. 设置一位停止位

	new_flags.c_cflag &= ~CSTOPB;

	// 8. 设置等待时间，最少接收字符个数

	new_flags.c_cc[VTIME] = 0;

	new_flags.c_cc[VMIN] = 1;

	// 9. 清空串口缓冲区

	tcflush(fd, TCIFLUSH);

	// 10. 设置串口的属性到文件中

	tcsetattr(fd, TCSANOW, &new_flags);

	return 0;
}

static void MYUSART_SendData(uint8_t data_num)

{

	uint8_t *data = &data_num;

	tcflush(fd, TCIFLUSH);

	write(fd, data, 1);
}

// 发送包头

static void SendHead(void)

{

	MYUSART_SendData(0xEF);

	MYUSART_SendData(0x01);
}

// 发送地址

static void SendAddr(void)

{

	MYUSART_SendData(AS608Addr >> 24);

	MYUSART_SendData(AS608Addr >> 16);

	MYUSART_SendData(AS608Addr >> 8);

	MYUSART_SendData(AS608Addr);
}

// 发送包标识,

static void SendFlag(uint8_t flag)

{

	MYUSART_SendData(flag);
}

// 发送包长度

static void SendLength(int length)

{

	MYUSART_SendData(length >> 8);

	MYUSART_SendData(length);
}

// 发送指令码

static void Sendcmd(uint8_t cmd)

{

	MYUSART_SendData(cmd);
}

// 发送校验和

static void SendCheck(uint16_t check)

{

	MYUSART_SendData(check >> 8);

	MYUSART_SendData(check);
}

// 判断中断接收的数组有没有应答包

// waittime为等待中断接收数据的时间（单位1ms）

// 返回值：数据包首地址

static uint8_t *JudgeStr(uint16_t waittime)

{

	uint8_t str[8];

	str[0] = 0xef;

	str[1] = 0x01;

	str[2] = AS608Addr >> 24;

	str[3] = AS608Addr >> 16;

	str[4] = AS608Addr >> 8;

	str[5] = AS608Addr;

	str[6] = 0x07;

	str[7] = '\0';

	while (--waittime)

	{

		usleep(1000);

		// 使用局部缓冲区接收数据

		int bytes_read = read(fd, rx_buffer, sizeof(rx_buffer));

		if (bytes_read > 0)

		{

			// 判断是否包含指定帧头

			char *found = strstr((const char *)rx_buffer, (const char *)str);

			if (found)

				return (uint8_t *)found;
		}
	}

	return 0;
}

// 录入图像 PS_GetImage

// 功能:探测手指，探测到后录入指纹图像存于ImageBuffer。

// 模块返回确认字

uint8_t PS_GetImage(void)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x01);

	temp = 0x01 + 0x03 + 0x01;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 生成特征 PS_GenChar

// 功能:将ImageBuffer中的原始图像生成指纹特征文件存于CharBuffer1或CharBuffer2

// 参数:BufferID --> charBuffer1:0x01	charBuffer1:0x02

// 模块返回确认字

uint8_t PS_GenChar(uint8_t BufferID)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x04);

	Sendcmd(0x02);

	MYUSART_SendData(BufferID);

	temp = 0x01 + 0x04 + 0x02 + BufferID;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 精确比对两枚指纹特征 PS_Match

// 功能:精确比对CharBuffer1 与CharBuffer2 中的特征文件

// 模块返回确认字

uint8_t PS_Match(void)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x03);

	temp = 0x01 + 0x03 + 0x03;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 搜索指纹 PS_Search

// 功能:以CharBuffer1或CharBuffer2中的特征文件搜索整个或部分指纹库.若搜索到，则返回页码。

// 参数:  BufferID @ref CharBuffer1	CharBuffer2

// 说明:  模块返回确认字，页码（相配指纹模板）

uint8_t PS_Search(uint8_t BufferID, uint16_t StartPage, uint16_t PageNum, SearchResult *p)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x08);

	Sendcmd(0x04);

	MYUSART_SendData(BufferID);

	MYUSART_SendData(StartPage >> 8);

	MYUSART_SendData(StartPage);

	MYUSART_SendData(PageNum >> 8);

	MYUSART_SendData(PageNum);

	temp = 0x01 + 0x08 + 0x04 + BufferID

		   + (StartPage >> 8) + (uint8_t)StartPage

		   + (PageNum >> 8) + (uint8_t)PageNum;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

	{

		ensure = data[9];

		p->pageID = (data[10] << 8) + data[11];

		p->mathscore = (data[12] << 8) + data[13];
	}

	else

		ensure = 0xff;

	return ensure;
}

// 合并特征（生成模板）PS_RegModel

// 功能:将CharBuffer1与CharBuffer2中的特征文件合并生成 模板,结果存于CharBuffer1与CharBuffer2

// 说明:  模块返回确认字

uint8_t PS_RegModel(void)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x05);

	temp = 0x01 + 0x03 + 0x05;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 储存模板 PS_StoreChar

// 功能:将 CharBuffer1 或 CharBuffer2 中的模板文件存到 PageID 号flash数据库位置。

// 参数:  BufferID @ref charBuffer1:0x01	charBuffer1:0x02

//       PageID（指纹库位置号）

// 说明:  模块返回确认字

uint8_t PS_StoreChar(uint8_t BufferID, uint16_t PageID)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x06);

	Sendcmd(0x06);

	MYUSART_SendData(BufferID);

	MYUSART_SendData(PageID >> 8);

	MYUSART_SendData(PageID);

	temp = 0x01 + 0x06 + 0x06 + BufferID

		   + (PageID >> 8) + (uint8_t)PageID;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 删除模板 PS_DeletChar

// 功能:  删除flash数据库中指定ID号开始的N个指纹模板

// 参数:  PageID(指纹库模板号)，N删除的模板个数。

// 说明:  模块返回确认字

uint8_t PS_DeletChar(uint16_t PageID, uint16_t N)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x07);

	Sendcmd(0x0C);

	MYUSART_SendData(PageID >> 8);

	MYUSART_SendData(PageID);

	MYUSART_SendData(N >> 8);

	MYUSART_SendData(N);

	temp = 0x01 + 0x07 + 0x0C

		   + (PageID >> 8) + (uint8_t)PageID

		   + (N >> 8) + (uint8_t)N;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 清空指纹库 PS_Empty

// 功能:  删除flash数据库中所有指纹模板

// 参数:  无

// 说明:  模块返回确认字

uint8_t PS_Empty(void)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x0D);

	temp = 0x01 + 0x03 + 0x0D;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 写系统寄存器 PS_WriteReg

// 功能:  写模块寄存器

// 参数:  寄存器序号RegNum:4\5\6

// 说明:  模块返回确认字

uint8_t PS_WriteReg(uint8_t RegNum, uint8_t DATA)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x05);

	Sendcmd(0x0E);

	MYUSART_SendData(RegNum);

	MYUSART_SendData(DATA);

	temp = RegNum + DATA + 0x01 + 0x05 + 0x0E;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	if (ensure == 0)

		printf("\r\n设置参数成功！");

	else

		printf("\r\n%s", EnsureMessage(ensure));

	return ensure;
}

// 读系统基本参数 PS_ReadSysPara

// 功能:  读取模块的基本参数（波特率，包大小等)

// 参数:  无

// 说明:  模块返回确认字 + 基本参数（16bytes）

uint8_t PS_ReadSysPara(SysPara *p)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x0F);

	temp = 0x01 + 0x03 + 0x0F;

	SendCheck(temp);

	data = JudgeStr(1000);

	if (data)

	{

		ensure = data[9];

		p->PS_addr = (data[11] << 24) | (data[12] << 16) | (data[13] << 8) | data[14];
		p->PS_max = (data[15] << 8) | data[16];
		p->PS_level = data[17];
		p->PS_size = data[18];
		p->PS_N = (data[19] << 8) | data[20];
	}

	else

		ensure = 0xff;

	if (ensure == 0x00)

	{

		printf("\r\n模块最大指纹容量=%d", p->PS_max);

		printf("\r\n对比等级=%d", p->PS_level);

		printf("\r\n地址=%x", p->PS_addr);

		printf("\r\n波特率=%d", p->PS_N * 9600);
	}

	else

		printf("\r\n%s", EnsureMessage(ensure));

	return ensure;
}

// 设置模块地址 PS_SetAddr

// 功能:  设置模块地址

// 参数:  PS_addr

// 说明:  模块返回确认字

uint8_t PS_SetAddr(uint32_t PS_addr)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x07);

	Sendcmd(0x15);

	MYUSART_SendData(PS_addr >> 24);

	MYUSART_SendData(PS_addr >> 16);

	MYUSART_SendData(PS_addr >> 8);

	MYUSART_SendData(PS_addr);

	temp = 0x01 + 0x07 + 0x15

		   + (uint8_t)(PS_addr >> 24) + (uint8_t)(PS_addr >> 16)

		   + (uint8_t)(PS_addr >> 8) + (uint8_t)PS_addr;

	SendCheck(temp);

	AS608Addr = PS_addr; // 发送完指令，更换地址

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	AS608Addr = PS_addr;

	if (ensure == 0x00)

		printf("\r\n设置地址成功！");

	else

		printf("\r\n%s", EnsureMessage(ensure));

	return ensure;
}

// 功能： 模块内部为用户开辟了256bytes的FLASH空间用于存用户记事本,

//	该记事本逻辑上被分成 16 个页。

// 参数:  NotePageNum(0~15),Byte32(要写入内容，32个字节)

// 说明:  模块返回确认字

uint8_t PS_WriteNotepad(uint8_t NotePageNum, uint8_t *Byte32)

{

	uint16_t temp = 0;

	uint8_t ensure = 0, i = 0;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(36);

	Sendcmd(0x18);

	MYUSART_SendData(NotePageNum);

	for (i = 0; i < 32; i++)

	{

		MYUSART_SendData(Byte32[i]);

		temp += Byte32[i];
	}

	temp = 0x01 + 36 + 0x18 + NotePageNum + temp;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

		ensure = data[9];

	else

		ensure = 0xff;

	return ensure;
}

// 读记事PS_ReadNotepad

// 功能：  读取FLASH用户区的128bytes数据

// 参数:  NotePageNum(0~15)

// 说明:  模块返回确认字+用户信息

uint8_t PS_ReadNotepad(uint8_t NotePageNum, uint8_t *Byte32)

{

	uint16_t temp;

	uint8_t ensure, i;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x04);

	Sendcmd(0x19);

	MYUSART_SendData(NotePageNum);

	temp = 0x01 + 0x04 + 0x19 + NotePageNum;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

	{

		ensure = data[9];

		for (i = 0; i < 32; i++)

		{

			Byte32[i] = data[10 + i];
		}
	}

	else

		ensure = 0xff;

	return ensure;
}

// 高速搜索PS_HighSpeedSearch

// 功能：以 CharBuffer1或CharBuffer2中的特征文件高速搜索整个或部分指纹库。

//		  若搜索到，则返回页码,该指令对于的确存在于指纹库中 ，且登录时质量

//		  很好的指纹，会很快给出搜索结果。

// 参数:  BufferID， StartPage(起始页)，PageNum（页数）

// 说明:  模块返回确认字+页码（相配指纹模板）

uint8_t PS_HighSpeedSearch(uint8_t BufferID, uint16_t StartPage, uint16_t PageNum, SearchResult *p)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x08);

	Sendcmd(0x1b);

	MYUSART_SendData(BufferID);

	MYUSART_SendData(StartPage >> 8);

	MYUSART_SendData(StartPage);

	MYUSART_SendData(PageNum >> 8);

	MYUSART_SendData(PageNum);

	temp = 0x01 + 0x08 + 0x1b + BufferID

		   + (StartPage >> 8) + (uint8_t)StartPage

		   + (PageNum >> 8) + (uint8_t)PageNum;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

	{

		ensure = data[9];

		p->pageID = (data[10] << 8) + data[11];

		p->mathscore = (data[12] << 8) + data[13];
	}

	else

		ensure = 0xff;

	return ensure;
}

// 读有效模板个数 PS_ValidTempleteNum

// 功能：读有效模板个数

// 参数: 无

// 说明: 模块返回确认字+有效模板个数ValidN

uint8_t PS_ValidTempleteNum(uint16_t *ValidN)

{

	uint16_t temp;

	uint8_t ensure;

	uint8_t *data;

	SendHead();

	SendAddr();

	SendFlag(0x01); // 命令包标识

	SendLength(0x03);

	Sendcmd(0x1d);

	temp = 0x01 + 0x03 + 0x1d;

	SendCheck(temp);

	data = JudgeStr(2000);

	if (data)

	{

		ensure = data[9];

		*ValidN = (data[10] << 8) + data[11];
	}

	else

		ensure = 0xff;

	if (ensure == 0x00)

	{

		printf("\r\neffective fingerprint number =%d", (data[10] << 8) + data[11]);
	}

	else

		printf("\r\n%s", EnsureMessage(ensure));

	return ensure;
}

// 与AS608握手 PS_HandShake

// 参数: PS_Addr地址指针

// 说明: 模块返新地址（正确地址）

uint8_t PS_HandShake(uint32_t *PS_Addr)

{

	SendHead();

	SendAddr();

	MYUSART_SendData(0x01); // Command

	MYUSART_SendData(0x00); // Data 1

	MYUSART_SendData(0x00); // Data 2

	usleep(200);

	uint8_t qbuf[64]; // 接收缓冲区

	int bytes_read = read(fd, qbuf, sizeof(qbuf));

	printf("bytes_read = %d\n", bytes_read);

	if (bytes_read > 0)
	{

		// 判断是不是模块返回的应答包

		if (qbuf[0] == 0xEF &&

			qbuf[1] == 0x01 &&

			qbuf[6] == 0x07)
		{

			*PS_Addr = (qbuf[2] << 24) | (qbuf[3] << 16) |

					   (qbuf[4] << 8) | qbuf[5];

			return 0;
		}
	}

	return 1;
}

// 模块应答包确认码信息解析

// 功能：解析确认码错误信息返回信息

// 参数: ensure

const char *EnsureMessage(uint8_t ensure)

{

	const char *p;

	switch (ensure)

	{

	case 0x00:
		p = "OK";
		break;

	case 0x01:
		p = "Packet reception error";
		break;

	case 0x02:
		p = "No finger detected on sensor";
		break;

	case 0x03:
		p = "Failed to capture fingerprint image";
		break;

	case 0x04:
		p = "Fingerprint image too dry or light to generate feature";
		break;

	case 0x05:
		p = "Fingerprint image too wet or blurred to generate feature";
		break;

	case 0x06:
		p = "Fingerprint image too messy to generate feature";
		break;

	case 0x07:
		p = "Image OK but insufficient features to generate template";
		break;

	case 0x08:
		p = "Fingerprint does not match";
		break;

	case 0x09:
		p = "No matching fingerprint found";
		break;

	case 0x0a:
		p = "Feature merge failed";
		break;

	case 0x0b:
		p = "Address out of fingerprint library range";
		break;

	case 0x10:
		p = "Failed to delete template";
		break;

	case 0x11:
		p = "Failed to empty fingerprint library";
		break;

	case 0x15:
		p = "No valid original image in buffer";
		break;

	case 0x18:
		p = "FLASH read/write error";
		break;

	case 0x19:
		p = "Undefined error";
		break;

	case 0x1a:
		p = "Invalid register number";
		break;

	case 0x1b:
		p = "Register value error";
		break;

	case 0x1c:
		p = "Invalid notepad page number";
		break;

	case 0x1f:
		p = "Fingerprint library is full";
		break;

	case 0x20:
		p = "Address error";
		break;

	default:
		p = "Unknown response code from module";
		break;
	}

	return p;
}

int golden_finger_init(void)
{
	fd = open("/dev/ttySAC2", O_RDWR | O_NOCTTY);

	if (fd < 0)
	{

		perror("Failed to open serial port");

		return -1;
	}

	// 初始化串口

	init_tty(fd);

	return fd;
}


int golden_finger(void)
{

	uint32_t moduleAddr = 0;

	uint8_t ret;

	// 打开串口设备（根据实际设备路径修改）

	// fd = open("/dev/ttySAC2", O_RDWR | O_NOCTTY);

	// if (fd < 0)
	// {

	// 	perror("Failed to open serial port");

	// 	return -1;
	// }

	// // 初始化串口

	// init_tty(fd);

	printf("Connecting to AS608 fingerprint module...\n");

	ret = PS_HandShake(&moduleAddr);

	if (ret == 0)
	{

		printf("Handshake successful! Module address: 0x%x\n", moduleAddr);
	}
	else
	{

		printf("Handshake failed, error code: %s\n", EnsureMessage(ret));

		//close(fd);

		return -1;
	}

	printf("Reading system parameters...\n");

	SysPara para;

	ret = PS_ReadSysPara(&para);

	if (ret == 0)
	{

		printf("Max fingerprint capacity: %d\n", para.PS_max);

		printf("Security level: %d\n", para.PS_level);

		printf("Module address: 0x%x\n", para.PS_addr);

		printf("Baud rate: %d bps\n", para.PS_N * 9600);
	}
	else
	{

		printf("Failed to read system parameters: %s\n", EnsureMessage(ret));
	}

	printf("Step 1: Detecting and capturing fingerprint image...\n");

	while (1)
	{

		ret = PS_GetImage();

		if (ret == 0x02)
		{

			printf("No finger detected on sensor.\n");
		}
		else if (ret != 0x00)
		{

			printf("Failed to capture image: %s\n", EnsureMessage(ret));
		}

		else
		{

			printf("✅ Fingerprint image captured successfully.\n");

			break;
		}
	}

	printf("Step 2: Generating feature from image (stored in CharBuffer1)...\n");

	ret = PS_GenChar(0x01); // 存入 CharBuffer1

	if (ret != 0x00)
	{

		printf("Failed to generate feature: %s\n", EnsureMessage(ret));

		//close(fd);

		return -1;
	}

	printf("✅ Feature generated and stored in CharBuffer1.\n");

	uint16_t pageId = 1; // 指定要保存的指纹模板页号（建议从1开始）

	printf("Step 3: Storing fingerprint template to flash (Page ID: %d)...\n", pageId);

	ret = PS_StoreChar(0x01, pageId); // 从 CharBuffer1 保存至 PageID=1

	if (ret != 0x00)
	{

		printf("Failed to store template: %s\n", EnsureMessage(ret));

		//close(fd);

		return -1;
	}

	printf("✅ Fingerprint template stored at Page ID: %d\n", pageId);

	printf("Step 4: Re-capturing image for verification...\n");
	while (1)
	{
		ret = PS_GetImage();

		if (ret == 0x02)
		{

			printf("No finger detected on sensor.\n");
		}
		else if (ret != 0x00)
		{

			printf("Failed to capture image: %s\n", EnsureMessage(ret));
		}

		else
		{

			printf("✅ Fingerprint image captured successfully.\n");

			break;
		}
	}
	printf("Step 5: Generating second feature (stored in CharBuffer2)...\n");
	ret = PS_GenChar(0x02); // 存入 CharBuffer2
	if (ret != 0x00)
	{
		printf("Failed to generate second feature: %s\n", EnsureMessage(ret));
		//close(fd);
		return -1;
	}

	printf("Step 6: Matching two features...\n");
	ret = PS_Match(); // 自动比对 CharBuffer1 & CharBuffer2
	if (ret == 0x00)
	{
		if (currentPage == PAY_PAGE && currentPayType == FINGER_PAY)
		{
			enter_pay_success_page_event();
		}

		printf("✅ Fingerprint match confirmed! Templates are identical.\n");
	}
	else if (ret == 0x08)
	{
		printf("❌ Fingerprint does not match.\n");
	}
	else if (ret == 0x02)
	{
		printf("❌ No finger detected during matching.\n");
	}
	else
	{
		printf("❌ Unknown error during matching: %s\n", EnsureMessage(ret));
	}

	//如果fd打开则关闭
	//close(fd);

	// printf("Fingerprint enrollment completed successfully!\n");

	return 0;
}

//关闭指纹识别设备
void close_finger_device()
{
	close(fd);
}

